package com.cskaoyan.service;

import com.cskaoyan.bean.bo.RegisterBO;
import com.cskaoyan.bean.bo.ResetBO;
import com.cskaoyan.bean.po.LoginUserData;
import com.cskaoyan.bean.po.MarketUser;
import com.cskaoyan.bean.po.MarketUserExample;
import com.cskaoyan.bean.po.UserInfoBean;
import com.cskaoyan.config.realm.CustomToken;
import com.cskaoyan.mapper.MarketUserMapper;
import com.cskaoyan.utils.PasswordGenerateUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

/**
 * @Auther: Yang Yi-zhou
 * @Date: 2022/9/12 11:17
 * @Description:
 */
@Service
public class WXAuthServiceImpl implements WXAuthService {
    @Autowired
    MarketUserMapper marketUserMapper;

    @Override
    public LoginUserData register(RegisterBO registerBO) {
        String username = registerBO.getUsername();
        String rawPassword = registerBO.getPassword();
        // 加密的password
        String hashedPassword = PasswordGenerateUtil.getHashedPassword(rawPassword);
        String mobile = registerBO.getMobile();

        MarketUser record = new MarketUser();
        record.setUsername(username);
        record.setPassword(hashedPassword);
        record.setMobile(mobile);
        record.setAddTime(new Date());
        record.setUpdateTime(new Date());
        int rows = marketUserMapper.insertSelective(record);
        if (rows > 0) {
            return login(username, rawPassword);
        }
        return null;
    }

    @Override
    public LoginUserData login(String username, String password) {

        // Shiro重构登陆业务
        // Subject登陆
        Subject subject = SecurityUtils.getSubject();
        // login需要一个AuthenticationToken接口类型的值，这里使用的的是该接口的实现类UsernamePasswordToken来封装username和password来生成一个token
        AuthenticationToken authenticationToken = new CustomToken(username, password, "wx");
        // 使用生成的token来做一个登陆的认证
//        try {
        // subject.login最后实际执行的是realm中的doGetAuthenticationInfo方法来做一个认证
        subject.login(authenticationToken);
//        } catch (AuthenticationException e) {
//            // 验证不通过，会包报一个IncorrectCredentialsException异常
//            throw new RuntimeException(e);
//        }
        // isAuthenticated()可以判断是否认证成功
        // ShiroFilter也是根据这个值来做过滤
        boolean authenticated = subject.isAuthenticated();

        // 获取Session
        Session session = subject.getSession();


        //subject.getPrincipals().getPrimaryPrincipal()来获取AuthenticationInfo中封装的Principal信息
//        MarketAdmin marketAdmin = (MarketAdmin) subject.getPrincipals().getPrimaryPrincipal();
        // 把用户信息放到session里
        MarketUser marketUser = (MarketUser) subject.getPrincipals().getPrimaryPrincipal();
        session.setAttribute("info", marketUser);
//        System.out.println(session.getId());
//        System.out.println(marketUser);

        LoginUserData loginUserData = new LoginUserData();
//        AdminInfoBean adminInfo = new AdminInfoBean();
        UserInfoBean userInfo = new UserInfoBean();
//        adminInfo.setAvatar("https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
//        adminInfo.setNickName("admin123");
        // 封装登陆用户的信息返回
        userInfo.setAvatar(marketUser.getAvatar());
        userInfo.setNickName(marketUser.getUsername());
        loginUserData.setUserInfo(userInfo);
//        loginUserData.setToken("c4d988f3-e4c5-4e46-b6ce-13b9e008ea20");
        // 封装SessionId作为Token返回
        loginUserData.setToken((String) session.getId());

        return loginUserData;
    }

    @Override
    public void reset(ResetBO resetBO) {
        String mobile = resetBO.getMobile();
        String password = resetBO.getPassword();
        String hashedPassword = PasswordGenerateUtil.getHashedPassword(password);

        MarketUser record = new MarketUser();
        record.setPassword(hashedPassword);
        MarketUserExample example = new MarketUserExample();
        example.createCriteria().andMobileEqualTo(mobile);
        int rows = marketUserMapper.updateByExampleSelective(record, example);
    }
}
